﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using SoftwareConsulting.BI11.Studio.Core.DBProviders;
using SoftwareConsulting.BI11.Studio.InternalServices;
using SoftwareConsulting.BI11.Studio.Core.Users.Properties;

namespace SoftwareConsulting.BI11.Studio.Core.Users
{
    /// <summary>
    /// Интерфейс списка пользователей системы
    /// </summary>
    public interface IUsersList
    {
        /// <summary>
        /// Возвращает текущего пользователя системы
        /// </summary>
        IUserInfo CurrentUser { get; }        
        /// <summary>
        /// Пытается подключиться к системе под указанным логином и паролем
        /// </summary>
        /// <param name="logOn"></param>
        /// <param name="password"></param>
        /// <returns>true - успешно, false - неудачно</returns>
        bool TryConnect(string logOn, string password);
        /// <summary>
        /// Создает нового пользователя
        /// </summary>
        /// <param name="newLogOn"></param>
        /// <param name="newPassword"></param>
        /// <param name="newLastName"></param>
        /// <param name="newFirstName"></param>
        /// <param name="newPatronymic"></param>
        /// <param name="newBirthDate"></param>
        /// <param name="newPost"></param>
        /// <param name="newTeam"></param>
        IUserInfo AddUser(string newLogOn, string newPassword, string newLastName, string newFirstName, string newPatronymic, DateTime newBirthDate, string newPost, Teams newTeam);
        /// <summary>
        /// Возвращает пользователя по его идентификатору
        /// </summary>
        /// <param name="needId"></param>
        /// <returns></returns>
        IUserInfo GetUserById(Guid needId);
    }

    /// <summary>
    /// Класс списка пользователей системы
    /// </summary>
    public sealed class UsersList:IUsersList
    {
        private SystemDBProvider _DB;
        private Hashtable _users;
        private IUserInfo _current;

        /// <summary>
        /// Возвращает текущего пользователя системы
        /// </summary>
        public IUserInfo CurrentUser
        {
            get
            {
                return _current;
            }            
        }

        /// <summary>
        /// Пытается подключиться к системе под указанным логином и паролем
        /// </summary>
        /// <param name="logOn"></param>
        /// <param name="password"></param>
        /// <returns>true - успешно, false - неудачно</returns>
        public bool TryConnect(string logOn, string password)
        {
            foreach (IUserInfo user in _users.Values)
            {
                if ((user.LogOn == logOn) && (user.Password == password))
                {
                    _current = user;
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Возвращает пользователя по его идентификатору
        /// </summary>
        /// <param name="needId"></param>
        /// <returns></returns>
        public IUserInfo GetUserById(Guid needId)
        {
            if (_users.ContainsKey(needId))
            {
                return _users[needId] as IUserInfo;
            }
            return null;
        }

        /// <summary>
        /// Создает нового пользователя
        /// </summary>
        /// <param name="newLogOn"></param>
        /// <param name="newPassword"></param>
        /// <param name="newLastName"></param>
        /// <param name="newFirstName"></param>
        /// <param name="newPatronymic"></param>
        /// <param name="newBirthDate"></param>
        /// <param name="newPost"></param>
        /// <param name="newTeam"></param>
        public IUserInfo AddUser(string newLogOn, string newPassword, string newLastName, string newFirstName, string newPatronymic, DateTime newBirthDate, string newPost, Teams newTeam)
        {
            IUserInfo user = new UserInfo(_DB);
            user.CreateAndBind(newLogOn, newPassword, newLastName, newFirstName, newPatronymic, newBirthDate, newPost, newTeam);
            _users.Add(user.Id, user);            
            return user;
        }

        /// <summary>
        /// Читает список имеющихся пользователей
        /// </summary>
        private void ReadList()
        {
            _users.Clear();
            string fname = Application.LocalUserAppDataPath + "\\" + Resources.BI_SYSTEM_FILENAME;
            if (!File.Exists(fname))
            {                
                _DB.Save(fname);
                AddUser("admin", "admin", string.Empty, string.Empty, string.Empty, Constants.NullDate, string.Empty, Teams.Admins);
                AddUser("head", "head", string.Empty, string.Empty, string.Empty, Constants.NullDate, string.Empty, Teams.Heads);
                AddUser("analyst", "analyst", string.Empty, string.Empty, string.Empty, Constants.NullDate, string.Empty, Teams.Analysts);
                AddUser("expert", "expert", string.Empty, string.Empty, string.Empty, Constants.NullDate, string.Empty, Teams.Experts);
                TryConnect("admin", "admin");                
                return;
            }
            _DB.Load(fname);            
            int c = _DB.GeneralRowsCount(SystemTable.Users);
            for (int i = 0; i < c; i++)
            {
                IUserInfo user = new UserInfo(_DB);
                user.Bind(_DB.GeneralGetRowValuesByIndex(SystemTable.Users, i));
                _users.Add(user.Id, user);
            }
        }

        /// <summary>
        /// Конструктор класса
        /// </summary>
        public UsersList(SystemDBProvider systemDB)
        {
            _DB = systemDB;
            _users = new Hashtable();
            ReadList();
        }
    }
}
